package com.rds.benchmark.config;

import com.rds.benchmark.util.MakeValue;

import java.util.ArrayList;
import java.util.List;

public class ArgvsConfig {

    public static String host = "localhost";
    public static int port = 6379;
    public static String mode = "single"; //连接模式 single | sentinel | cluster

    public static String password = null;
    public static String masterName = "WebSession";
    public static String sentinelPassword = null;

    public static int threads = 50;
    public static long milliTime = 120 * 1000;

    public static int Start = 0;
    public static int Stop = 16383;

    public static Integer requests = null;
    public static boolean random = false;

    public static int cmd = 0;

    public static String  clientType = "jedis";
    public static String[] commands = null;
    private static String[] commandParam = new String[]{"set","get","scan","del","incr","hset","hget","hgetall","hscan",
                                                            "hdel","lpush","lpop","rpush","rpop","lrange","sort","lrem","sadd","smembers","sscan","srem",
                                                            "spop","sismember","srandmember","zadd","zrange","zrevrange","zunionstore","zinterstore","zscan","zrem","ping","mset",
                                                            "hincrBy","hmset","zpopmin","zpopmax"};
    public static List<String> randomCommands;


    public static void Usage() {
        System.out.println("\nUsage: java -jar benchmark-1.x.jar [-h host] [-p port] [-a password] [-t thread] [-c cmd] [--time duration] [--range start-stop]\n");
        System.out.println(" -h or --host   <hostname>                       Server hostname (default 127.0.0.1)");
        System.out.println(" -p or --port   <port>                           Server port (default 6379)");
        System.out.println(" -m or --mode   <connection mode>                Connection mode, optional values: single, sentinel, cluster (default single)"); // TODO 新加
        System.out.println(" -a or --pass   <password>                       The password to login (default null)");
        System.out.println(" -n or --mastername   <master name>              Server mastername (default WebSession)");
        System.out.println(" -s or --sentinelpassword   <sentinel password>  Server sentinelpassword (default null)");
        System.out.println(" -t or --thread   <clients>                      Number of parallel connections (default " + threads + ")");
        System.out.println(" -d <size>                                       Data size of SET/GET value in bytes (default 6)");
        System.out.println(" --time   <duration>                             Test run time, in seconds (default 120)");
        System.out.println(" --range  <start-stop>                           The slot range of the key (default 0-16383)");
        System.out.println(" --client  <clienttype>                          The client type : jedis , redisson , lettuce");
        System.out.println(" --number                                        Total number of requests");
        System.out.println(" -r or --random                                  Use random keys ");
        System.out.println(" -c <cmd> <cmd-list>                             Data type to test, optional values: string, list, set, hash, zset, publish, w1r9, write, read, w1r1, redis(command),\\");
        System.out.println("                                                 stable(7 * 24 stability test), all(include string,list,set,hash,zset,publish), (default string)");
        System.out.println(" --command  <cmd> <cmd-list>                     Data type to test, optional values: set,get,scan,del,incr,hset,hget,hgetall,hscan,hdel,lpush,lpop,rpush,rpop,lrange,sort,lrem,sadd,smembers,sscan,srem,\\");
        System.out.println("                                                 spop,sismember,srandmember,zadd,zrange,zrevrange,zunionstore,zinterstore,zscan,zrem,ping,mset,hincrby,hmset,zpopmin,zpopmax");
        System.out.println(" --help                                          this message");
        System.out.println();
        System.exit(0);
    }

    public static void init(String[] argv) {
        // 解析参数
        for (int i = 0; i < argv.length; i++) {
            if ("-h".equalsIgnoreCase(argv[i])
                    || "--host".equalsIgnoreCase(argv[i])) {
                if (i + 1 < argv.length) {
                    host = argv[++i];
                } else {
                    System.out.println("invalid parameter -h");
                    Usage();
                }
            } else if ("-p".equalsIgnoreCase(argv[i])
                    || "--port".equalsIgnoreCase(argv[i])) {
                try {
                    port = Integer.parseInt(argv[++i]);
                } catch (Exception e) {
                    System.out.println("invalid parameter -p: " + e.getMessage());
                    Usage();
                }
            } else if ("-m".equalsIgnoreCase(argv[i])
                    || "--mode".equalsIgnoreCase(argv[i])) {
                if (i + 1 < argv.length) {
                    mode = argv[++i];
                } else {
                    System.out.println("invalid parameter -m");
                    Usage();
                }
            } else if ("-n".equalsIgnoreCase(argv[i])
                    || "--mastername".equalsIgnoreCase(argv[i])) {
                if (i + 1 < argv.length) {
                    masterName = argv[++i];
                } else {
                    System.out.println("invalid parameter -n");
                    Usage();
                }
            } else if ("-s".equalsIgnoreCase(argv[i])
                    || "--sentinelpassword".equalsIgnoreCase(argv[i])) {
                if (i + 1 < argv.length) {
                    sentinelPassword = argv[++i];
                } else {
                    System.out.println("invalid parameter -s");
                    Usage();
                }
            } else if ("-t".equalsIgnoreCase(argv[i])
                    || "--thread".equalsIgnoreCase(argv[i])) {
                try {
                    threads = Integer.parseInt(argv[++i]);
                } catch (Exception e) {
                    System.out.println("invalid parameter -t: " + e.getMessage());
                    Usage();
                }
            }else if ("--command".equalsIgnoreCase(argv[i])) {
                String command = argv[++i];
                commands = command.split(",");
            }else if ("-c".equalsIgnoreCase(argv[i])) {
                String command = argv[++i];
                if ("string".equalsIgnoreCase(command)) {
                    cmd = 0;
                } else if ("list".equalsIgnoreCase(command)) {
                    cmd = 1;
                } else if ("set".equalsIgnoreCase(command)) {
                    cmd = 2;
                } else if ("hash".equalsIgnoreCase(command)) {
                    cmd = 3;
                } else if ("zset".equalsIgnoreCase(command)) {
                    cmd = 4;
                } else if ("publish".equalsIgnoreCase(command)) {
                    cmd = 5;
                } else if ("w1r9".equalsIgnoreCase(command)) {
                    cmd = 6;
                } else if ("write".equalsIgnoreCase(command)) {
                    cmd = 7;
                } else if ("read".equalsIgnoreCase(command)) {
                    cmd = 8;
                } else if ("w1r1".equalsIgnoreCase(command)) {
                    cmd = 9;
                } else if ("stable".equalsIgnoreCase(command)) {
                    cmd = 90;
                } else if ("redis".equalsIgnoreCase(command)) {
                    cmd = 99;
                } else if ("all".equalsIgnoreCase(command)) {
                    cmd = 100;
                }
            } else if ("--time".equalsIgnoreCase(argv[i])) {
                try {
                    milliTime = Long.parseLong(argv[++i]) * 1000;
                } catch (Exception e) {
                    System.out.println("invalid parameter --time: " + e.getMessage());
                    Usage();
                }
            } else if ("--range".equalsIgnoreCase(argv[i])) {
                String range = argv[++i];
                try {
                    String[] rs = range.split("-");
                    if (rs != null && rs.length > 0) {
                        Start = Integer.parseInt(rs[0]);
                        if (rs.length > 1) {
                            Stop = Integer.parseInt(rs[1]);
                        }
                    }
                } catch (Throwable t) {
                    System.err.println("Error range: " + range);
                }
                System.out.println("Range of slot is [" + Start + " - " + Stop + "]");
            } else if ("-a".equalsIgnoreCase(argv[i]) || "--pass".equalsIgnoreCase(argv[i])) {
                password = argv[++i];
            } else if ("-d".equalsIgnoreCase(argv[i])) {
                MakeValue.make(argv[++i]);
            } else if ("--number".equalsIgnoreCase(argv[i])) {
                String tNumber = argv[++i];
                try {
                    requests = Integer.parseInt(tNumber);
                } catch (Exception e) {
                    System.err.println("Error number: " + tNumber);
                }
            } else if ("-r".equalsIgnoreCase(argv[i])
                    || "--random".equalsIgnoreCase(argv[i])) {
                random = true;
            } else if ("--client".equalsIgnoreCase(argv[i])) {
                clientType = argv[++i];
            } else if ("--help".equalsIgnoreCase(argv[i])) {
                Usage();
            } else {
                System.err.println("\nUnknown parameter: " + argv[i] + "\n");
                Usage();
            }
        }

        System.out.println();
        System.out.println("EndPoint: " + host + ":" + port);
        System.out.println("Concurrent clients: " + threads);
        System.out.println();

        if(commands == null)commands = commandParam;

        if (requests != null) {
            if (requests < threads) {
                // 执行命令数量小于线程数，让线程数 等于 执行命令数量
                threads = requests;
            }
        }

        randomCommands = new ArrayList<String>();
        randomCommands.add("lpush");
        randomCommands.add("hset");
        randomCommands.add("sadd");
        randomCommands.add("zadd");
        randomCommands.add("rpush");
        randomCommands.add("hget");
        randomCommands.add("hdel");
        randomCommands.add("lrem");
        randomCommands.add("srem");
        randomCommands.add("sismember");
        randomCommands.add("zrem");
        randomCommands.add("mset");
        randomCommands.add("hincrby");
        randomCommands.add("hmset");
    }
}
